package com.nut.lmsc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nut.lmsc.api.resp.DeptVo;
import com.nut.lmsc.common.Result;
import com.nut.lmsc.entity.SysDept;
import com.nut.lmsc.mapper.SysDeptMapper;
import com.nut.lmsc.service.SysDeptService;
import com.nut.lmsc.util.DeptCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class SysDeptServiceImpl implements SysDeptService {

    public static final ConcurrentHashMap<Integer, List<String>> CACHE = new ConcurrentHashMap<>();

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Override
    public List<SysDept> list(String name) {
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasLength(name)) {
            queryWrapper.like(SysDept::getName, name);
        }
        queryWrapper.orderByAsc(SysDept::getSort);
        return sysDeptMapper.selectList(queryWrapper);
    }

    @Override
    public SysDept getById(Integer id) {
        return sysDeptMapper.selectById(id);
    }

    @Override
    public void save(SysDept sysDept) {
        Integer pid = sysDept.getPid();
        String deptCode;
        //自动生成部门编号
        String maxDeptCode = sysDeptMapper.selectMaxDeptCode(pid);
        if (maxDeptCode == null) {
            SysDept dept = sysDeptMapper.selectById(pid);
            deptCode = DeptCodeUtil.getSubDeptCode(dept.getCode());
        } else {
            deptCode = DeptCodeUtil.nextDeptCode(maxDeptCode);
        }

        sysDept.setCode(deptCode);
        sysDeptMapper.insert(sysDept);
        updateSubCount(sysDept.getPid());
    }

    @Override
    public void updateById(SysDept sysDept) {
        sysDeptMapper.updateById(sysDept);
        updateSubCount(sysDept.getPid());
    }

    /**
     * 更新父节点的 是否有子节点标识
     *
     * @param pid
     */
    private void updateSubCount(Integer pid) {
        if (pid == null || pid == 0) {
            return;
        }

        Integer count = sysDeptMapper.selectCount(new LambdaQueryWrapper<SysDept>().eq(SysDept::getPid, pid));

        SysDept sysDept = new SysDept();
        sysDept.setId(pid);
        sysDept.setSubCount(count);
        sysDeptMapper.updateById(sysDept);
    }

    @Override
    public List<SysDept> getByPid(Integer pid) {
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDept::getPid, pid);
        queryWrapper.orderByAsc(SysDept::getSort);
        return sysDeptMapper.selectList(queryWrapper);
    }

    @Override
    public List<DeptVo> getSuperior(Integer id, List<DeptVo> depts) {
        if (id == null) {
            return getByPidVo(0);
        }

        SysDept dept = sysDeptMapper.selectById(id);
        Integer pid = dept.getPid();
        if (pid == 0) {
            depts.addAll(getByPidVo(0));
            return depts;
        }
        depts.addAll(getByPidVo(pid));
        return getSuperior(pid, depts);
    }

    private List<DeptVo> getByPidVo(Integer pid) {
        List<SysDept> depts = getByPid(pid);
        ArrayList<DeptVo> list = new ArrayList<>();
        for (SysDept dept : depts) {
            DeptVo deptVo = new DeptVo();
            deptVo.setId(dept.getId());
            deptVo.setPid(dept.getPid());
            deptVo.setName(dept.getName());
            deptVo.setCode(dept.getCode());
            list.add(deptVo);
        }
        return list;
    }

    @Override
    public List<DeptVo> buildTree(List<DeptVo> depts) {
        ArrayList<DeptVo> list = new ArrayList<>(depts.size());

        for (DeptVo deptVo : depts) {
            if (deptVo.getPid() == 0) {
                list.add(deptVo);
            }

            for (DeptVo sysMenu : depts) {
                if (sysMenu.getId().equals(deptVo.getPid())) {
                    if (deptVo.getChild() == null) {
                        deptVo.setChild(new ArrayList<>());
                    }
                    deptVo.getChild().add(sysMenu);
                }
            }
        }

        return list;
    }

    @Override
    public Result deleteByIds(Set<Integer> ids) {
        sysDeptMapper.deleteBatchIds(ids);
        return Result.ok();
    }


}
